﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Globalization;
using System.IO;

namespace ConfirmExtender
{
    /// <summary>
    /// Extends another control with a confirmation message dialog.
    /// </summary>
    public class ConfirmationExtender : Control
    {
        /// <summary>
        /// Gets or sets the target control ID.
        /// </summary>
        /// <value>The target control ID.</value>
        public string TargetControlId
        {
            get
            {
                string value = (string)ViewState["TargetControlID"];
                if (value == null)
                    value = string.Empty;
                return value;
            }
            set
            {
                ViewState["TargetControlID"] = value;
            }
        }


        /// <summary>
        /// Gets or sets the confirmation message.
        /// </summary>
        /// <value>The confirmation message.</value>
        public string ConfirmationMessage
        {
            get
            {
                string value = (string)ViewState["ConfirmationMessage"];
                if (value == null)
                    value = string.Empty;
                return value;
            }
            set
            {
                ViewState["ConfirmationMessage"] = value;
            }
        }


        /// <summary>
        /// Raises the <see cref="E:System.Web.UI.Control.PreRender"/> event.
        /// </summary>
        /// <param name="e">An <see cref="T:System.EventArgs"/> object that contains the event data.</param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            if (FindTargetControl().Visible)
            {
                Page.ClientScript.RegisterStartupScript(typeof(ConfirmationExtender),
                    "Confirmation" + UniqueID, BuildStartupScript(), true);
            }
        }


        /// <summary>
        /// Builds the startup script.
        /// </summary>
        /// <returns>The startup script.</returns>
        private string BuildStartupScript()
        {
            // find the target control and prepare the confirmation message
            Control target = FindTargetControl();
            string confirmationMessage = ConfirmationMessage
                .Replace("'", @"\'");

            // build the startup script
            string startupScript = RetrieveEmbeddedResource("ConfirmationExtender.js")
                .Replace("%ClientID%", ClientID)
                .Replace("%TargetClientID%", target.ClientID)
                .Replace("%ConfirmationMessage%", confirmationMessage);

            return startupScript;
        }


        /// <summary>
        /// Finds the target control.
        /// </summary>
        /// <returns>The target control.</returns>
        protected Control FindTargetControl()
        {
            return NamingContainer.FindControl(TargetControlId);
        }


        /// <summary>
        /// Retrieves the embedded resource with the given name.
        /// </summary>
        private static string RetrieveEmbeddedResource(string name)
        {
            using (Stream stream = typeof(ConfirmationExtender).Assembly.GetManifestResourceStream(
                typeof(ConfirmationExtender), name))
            {
                if (stream == null)
                    throw new ArgumentException(
                        String.Format(CultureInfo.InvariantCulture,
                            "No resource with name '{0}' could be located.", name),
                        "name");

                StreamReader reader = new StreamReader(stream);
                return reader.ReadToEnd();
            }
        }
    }
}